import {IGameScene} from "../base/IGameScene";
import {Player} from "../base/Player";
import {ChatMessageType} from "../../Constants";
import {GameData_nbddz} from "./public/GameData_nbddz";
import {BankerAction, CARDS_TO_HEX_STR, Comb, EndType, GAME_STEP, MAX_PLAYER, PlayerAction} from "./public/GameDefine_nbddz";
import {PlayCardEvent, PlayCardUI} from "../component/PlayCardUI";
import {GameLogic_nbddz} from "./public/GameLogic_nbddz";
import {TableData} from "../TableData";
import {CARD_BACK, HERO_LOCAL_SEAT, HintData} from "./GameLocal_nbddz";
import {PlayerData} from "../PlayerData";
import {PlayerPost} from "../PlayerPost";
import {HINT_TYPE, HintUI} from "../../custom/HintUI";
import {network} from "../../common/network";
import {cmd} from "../../common/cmdClient";
import {DispatcherUtils} from "../../util/DispatcherUtils";
import {Event} from "../../Event";
import {InfoModule} from "../../logic/InfoModule";
import {NbddzPlayerUI} from "./NbddzPlayerUI";
import NbddzGameEndUI from "./NbddzGameEndUI";

const {ccclass, property} = cc._decorator;

@ccclass
export default class NbDouDiZhuScene  extends cc.Component implements IGameScene{
    @property([NbddzPlayerUI])
    players:Array<NbddzPlayerUI> = [];
    @property(PlayCardUI)
    heroHandCards:PlayCardUI = null;
    @property(NbddzGameEndUI)
    gameEndUI:NbddzGameEndUI = null;
    @property(cc.Node)
    tableBtnNode = null;
    @property(cc.Node)
    gameBtnNode = null;
    @property(cc.Node)
    jiaoBtnNode = null;
    @property(cc.Node)
    readyBtnNode = null;
    @property(PlayCardUI)
    diPaiCards:PlayCardUI = null;
    @property(cc.Label)
    diFen:cc.Label = null;
    data:GameData_nbddz;
    logic:GameLogic_nbddz;
    step:GAME_STEP;
    relink:boolean;
    lastUpCards = [];
    onLoad () {
        cc.debug.setDisplayStats(false);
        PlayerPost.init(this);
        this.data = new GameData_nbddz();
        this.logic = new GameLogic_nbddz();
        this.logic.init();
        this.step = GAME_STEP.NULL;
        this.relink = false;
        this.init();
        PlayerPost.enterTable();
        network.addHandler(cmd.game_main_msg,this.onReceiveMessage,this);
        //TODO 暂时先这样
        DispatcherUtils.addAutoEventListener(Event.LOGIN_SUCCESS,function () {
            InfoModule.relinkRoom();
        })
        this.heroHandCards.node.on(PlayCardEvent.ON_CLEAR_ALL_CARD_UP,this.onClearAllCardUp,this);
        this.heroHandCards.node.on(PlayCardEvent.ON_SELECTED_CARD,this.onSelectCard,this);
        this.heroHandCards.node.on(PlayCardEvent.ON_FRAME_SELECTED_CARD,this.onFrameSelectedCard,this);
    }

    onPlayerEnter(localSeat: number, player: Player) {
        this.players[localSeat].init();
        this.players[localSeat].showName(true,player.nickname);
        this.players[localSeat].showBodyGold(true,player.gold);
        //this.players[localSeat].showHead(true,player.headimg);
        this.players[localSeat].setVisible(true);
        this.players[localSeat].showReady(player.isReady());
        this.players[localSeat].showOffline(player.isDisconnected());
    }

    onPlayerStatus(localSeat: number, player: Player) {
        this.players[localSeat].showReady(player.isReady());
        this.players[localSeat].showOffline(player.isDisconnected());
        if(localSeat == HERO_LOCAL_SEAT){
            this.readyBtnNode.active = !player.isReady();
        }
    }

    onPlayerGameData(localSeat: number, player: Player) {
        this.players[localSeat].showBodyGold(true,player.gold);
    }

    onPlayerLeave(localSeat: number, player: Player) {
        this.players[localSeat].setVisible(false);
    }

    onLeaveRoom() {
        //cc.director.loadScene("LobbyScene");
    }

    onChat(localSeat: number, type: ChatMessageType, content: string) {

    }

    onGameInfo() {
        this.onGameStatusChanged();
    }

    onGameStatusChanged() {
        this.tableBtnNode.active = !TableData.isGameProcessing();
        if(!TableData.isGameProcessing()){
            this.gameBtnNode.active = false;
            this.jiaoBtnNode.active = false;
        }
    }
    /////////////////////////////////////////////////////////////////////////////////////
    onClickTableBtn(e,data){
        if(data == "换桌"){
            //TODO
            console.log("暂不支持换桌");
            //this.players[0].showClock(true,30,30);
        }else if(data == "准备"){
            PlayerPost.sendReady();
        }else if(data == "离开"){
            if(TableData.isGameProcessing()){
                HintUI.show("强退房间后会托管至结束，是否强退",HINT_TYPE.TWO,function (flag) {
                    if(flag){
                        PlayerPost.leaveRoom();
                    }
                })
            }else{
                PlayerPost.leaveRoom();
            }
        }
    }

    onClickGameBtn(e,data){
        if(data == "不出"){
            console.log("不出");
            this.sendMessage("game_action",{
                action:PlayerAction.NOT_PLAY
            })
        }else if(data == "提示"){
            console.log("提示");
            let comb = HintData.getNextHint();
            if(comb!=null){
                console.log(comb);
                this.heroHandCards.clearAllCardUp();
                this.heroHandCards.setCardsUp(comb.cards,true);
                this.checkPlayBtnEnabled();
            }
        }else if(data == "出牌"){
            console.log("出牌");
            let out = this.heroHandCards.getUpCardsValue();
            let comb = this.logic.get_bigger_comb(out,this.data.preComb);
            if(comb != null){
                this.sendMessage("game_action",{
                    action:PlayerAction.PLAY,
                    comb:comb,
                })
            }else{
                HintUI.show("非法牌型");
            }
        }
    }

    onClickJiaoBtn(e,data){
        if(data == "不抢"){
            this.sendMessage("game_jiao_action",{
                action:BankerAction.NOT_QIANG
            })
        }else if(data == "1分"){
            this.sendMessage("game_jiao_action",{
                action:BankerAction.QIANG_1
            })
        }else if(data == "2分"){
            this.sendMessage("game_jiao_action",{
                action:BankerAction.QIANG_2
            })
        }else if(data == "3分"){
            this.sendMessage("game_jiao_action",{
                action:BankerAction.QIANG_3
            })
        }
    }
    checkPlayBtnEnabled(){
        let out = this.heroHandCards.getUpCardsValue();
        this.lastUpCards = out;
        console.log(CARDS_TO_HEX_STR(out));
        if(out.length == 0){
            cc.find("btn_play",this.gameBtnNode).getComponent(cc.Button).interactable = false;
            return;
        }
        let comb = this.logic.get_bigger_comb(out,this.data.preComb);
        if(comb != null){
            cc.find("btn_play",this.gameBtnNode).getComponent(cc.Button).interactable = true;
            console.log(comb);
        }else{
            cc.find("btn_play",this.gameBtnNode).getComponent(cc.Button).interactable = false;
        }
    }

    onClearAllCardUp(){
        //console.log(PlayCardEvent.ON_CLEAR_ALL_CARD_UP);
        this.checkPlayBtnEnabled();
    }

    onSelectCard(){
        console.log(PlayCardEvent.ON_SELECTED_CARD);
        let up = this.heroHandCards.getUpCardsValue();
        let isUpFlag = up.length>this.lastUpCards.length;
        console.log(up.length,this.lastUpCards.length);
        this.lastUpCards = up;
        if(isUpFlag){
            let needUpCards = HintData.getCardsBySelectCard(up);
            console.log(HintData.canOutCombs,needUpCards);
            if(needUpCards.length>0){
                this.heroHandCards.setCardsUp(needUpCards,true);
            }
        }
        this.checkPlayBtnEnabled();
    }

    onFrameSelectedCard(){
        console.log(PlayCardEvent.ON_FRAME_SELECTED_CARD);

        let up = this.heroHandCards.getUpCardsValue();
        let isUpFlag = up.length>this.lastUpCards.length;
        this.lastUpCards = up;
        if(isUpFlag) {
            let needUpCards = HintData.getUpByFrameSelectCard(up);
            if (needUpCards.length > 0) {
                this.heroHandCards.clearAllCardUp();
                this.heroHandCards.setCardsUp(needUpCards, true);
            }
        }
        this.checkPlayBtnEnabled();
    }
    /////////////////////////////////////////////////////////////////////////////////////
    init(){
        for(let i = 0 ;i<this.players.length;i++){
            this.players[i].init();
            this.players[i].setVisible(false);
        }
        this.gameBtnNode.active = false;
        this.jiaoBtnNode.active = false;
        this.diPaiCards.setCards([]);
        this.diFen.string="";
        this.data.reset();
    }

    sendMessage(event,msg?){
        let data = {
            event:event,
            data:msg,
        };
        network.sendMsg(cmd.game_main_msg,data)
    }
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    onReceiveMessage(e) {
        let event = e.event;
        let msg = e.data;
        console.log(event,msg);
        if(event == "game_start"){
            this.onGameStart();
        }else if(event == "game_reconnect"){
            this.relink = true;
        }else if(event == "game_reconnect_over"){
            this.relink = false;
        }else if(event == "game_step"){
            this.onStep(msg);
        }else if(event == "game_hand_card"){
            this.onHandCard(msg);
        }else if(event == "game_hand_back") {
            this.onBackCard(msg);
        }else if(event == "game_take_first") {
            this.onTakeFirst();
        }else if(event == "game_round") {
            this.onRound(msg);
        }else if(event == "game_power") {
            this.onPower(msg);
        }else if(event == "game_clock") {
            this.onClock(msg);
        }else if(event == "game_action") {
            this.onAction(msg);
        }else if(event == "game_all_action") {
            this.onAllAction(msg);
        }else if(event == "game_all_hands") {
            this.onAllHands(msg);
        }else if(event == "game_win_lost") {
            this.onWinLost(msg);
        //斗地主协议
        }else if(event == "game_jiao_power") {
            this.onJiaoPower(msg);
        }else if(event == "game_banker") {
            this.onBanker(msg);
        }else if(event == "game_dipai") {
            this.onDiPai(msg);
        }else if(event == "game_difen") {
            this.onDiFen(msg);
        }else if(event == "game_jiao_action") {
            this.onJiaoAction(msg);
        }else if(event == "game_all_jiao_action") {
            this.onAllJiaoAction(msg);
        }
    }

    onGameStart(){
        for(let i = 0 ;i<this.players.length;i++){
            this.players[i].init();
        }
        this.data.reset();
    }

    onStep(msg){
        this.step = msg.step;
    }

    onHandCard(msg){
        let localSeat = PlayerData.serverSeatToLocalSeat(msg.seat);
        this.data.handCards[localSeat] = msg.cards;
        this.logic.sort_cards_by_size_down(this.data.handCards[localSeat])
        if(this.relink || msg.refresh){
            let playerUI = this.players[localSeat];
            let hand = this.data.handCards[localSeat];
            playerUI.showHandCard(true,hand,false);
        }
    }

    onBackCard(msg){
        let localSeat = PlayerData.serverSeatToLocalSeat(msg.seat);
        this.data.handCards[localSeat] = new Array(msg.count).fill(CARD_BACK);
        if(this.relink || msg.refresh){
            let playerUI = this.players[localSeat];
            let hand = this.data.handCards[localSeat];
            playerUI.showHandCard(true,hand,false);
        }
    }

    onTakeFirst(){
        for(let localSeat =0;localSeat<MAX_PLAYER;localSeat++){
            let player = PlayerData.getPlayerByLocalSeat(localSeat);
            if(player){
                this.players[localSeat].showHandCard(true,this.data.handCards[localSeat],true);
            }
        }
    }

    onPower(msg){
        if(msg.seat != PlayerData.getHero().seat){
            this.gameBtnNode.active = false;
            return;
        }

        this.players[HERO_LOCAL_SEAT].showNotOut(false);
        this.players[HERO_LOCAL_SEAT].showOutCard(false);
        this.gameBtnNode.active = true;
        cc.find("btn_no",this.gameBtnNode).getComponent(cc.Button).interactable = (msg.power & PlayerAction.NOT_PLAY)>0;
        HintData.init(this.logic,this.data.handCards[HERO_LOCAL_SEAT],this.data.preComb);
        this.checkPlayBtnEnabled();
    }

    onClock(msg){
        let localSeat = PlayerData.serverSeatToLocalSeat(msg.seat);
        for(let i = 0;i<MAX_PLAYER;i++){
            if(localSeat == i) this.players[i].showClock(true,msg.time,msg.remain);
            else this.players[i].showClock(false);
        }
    }

    onRound(msg){
        this.data.preComb = msg.preComb;
        this.data.preSeat = msg.preSeat;
        if(this.data.preComb == null){
            for(let i=0;i<this.players.length;i++){
                let playerUI = this.players[i];
                playerUI.showNotOut(false);
                playerUI.showOutCard(false);
            }
        }
    }

    onAction(msg){
        let localSeat = PlayerData.serverSeatToLocalSeat(msg.seat);
        if(localSeat == HERO_LOCAL_SEAT) this.gameBtnNode.active = false;
        let action = msg.action;

        let playerUI = this.players[localSeat];
        playerUI.showClock(false);
        if(action == PlayerAction.NOT_PLAY){
            playerUI.showNotOut(true);
            playerUI.showOutCard(false);
        }else if(action == PlayerAction.PLAY){
            let outs = msg.comb.cards;
            playerUI.showNotOut(false);
            this.logic.sort_cards_by_size_down(outs);
            playerUI.showOutCard(true,outs);
            if(localSeat != HERO_LOCAL_SEAT){
                outs = new Array(outs.length).fill(CARD_BACK);
            }
            this.logic.del_sub_cards(this.data.handCards[localSeat],outs);
            this.logic.sort_cards_by_size_down(this.data.handCards[localSeat]);
            playerUI.showHandCard(true,this.data.handCards[localSeat]);
        }
    }

    onAllAction(msg){
        for(let seat=0;seat<MAX_PLAYER;seat++){
            let localSeat = PlayerData.serverSeatToLocalSeat(seat);
            let playerUI = this.players[localSeat];
            let action = msg.action[seat];
            let outs = msg.cards[seat];
            if(action == PlayerAction.NOT_PLAY){
                playerUI.showNotOut(true);
            }else if(action == PlayerAction.PLAY){
                this.logic.sort_cards_by_size_down(outs);
                playerUI.showOutCard(true,outs);
            }
        }
    }

    onAllHands(msg){
        for(let seat=0;seat<MAX_PLAYER;seat++){
            let localSeat = PlayerData.serverSeatToLocalSeat(seat);
            let playerUI = this.players[localSeat];
            let hands = msg.cards[seat];
            this.logic.sort_cards_by_size_down(hands);
            if(localSeat == HERO_LOCAL_SEAT){
                playerUI.showHandCard(true,hands);
            }else{
                playerUI.showHandCard(false);
                playerUI.showOutCard(true,hands);
            }
        }
    }

    onWinLost(msg){
        this.gameEndUI.show(this.data.bankerSeat,msg);
    }

    onJiaoPower(msg:{seat:number,power:number}){
        if(msg.seat != PlayerData.getHero().seat){
            this.jiaoBtnNode.active = false;
            return;
        }
        this.jiaoBtnNode.active = true;
        cc.find("btn_bu_qiang",this.jiaoBtnNode).getComponent(cc.Button).interactable = (msg.power & BankerAction.NOT_QIANG)>0;
        cc.find("btn_1_fen",this.jiaoBtnNode).getComponent(cc.Button).interactable = (msg.power & BankerAction.QIANG_1)>0;
        cc.find("btn_2_fen",this.jiaoBtnNode).getComponent(cc.Button).interactable = (msg.power & BankerAction.QIANG_2)>0;
        cc.find("btn_3_fen",this.jiaoBtnNode).getComponent(cc.Button).interactable = (msg.power & BankerAction.QIANG_3)>0;
    }

    onBanker(msg:{seat:number}){
        let localSeat = PlayerData.serverSeatToLocalSeat(msg.seat);
        let playerUI = this.players[localSeat];
        playerUI.showDiZhu(true)
        this.data.bankerSeat=msg.seat;
    }

    onDiPai(msg:{cards:Array<number>}){
        this.diPaiCards.setCards(msg.cards);
    }

    onDiFen(msg:{base:number}){
        this.diFen.string=msg.base+"分"
        //隐藏状态
        for(let seat=0;seat<MAX_PLAYER;seat++){
            let localSeat = PlayerData.serverSeatToLocalSeat(seat);
            let playerUI = this.players[localSeat];
            playerUI.showJiaoType(false);
        }
    }

    onJiaoAction(msg:{seat:number ,action:BankerAction}){
        let localSeat = PlayerData.serverSeatToLocalSeat(msg.seat);
        if(localSeat == HERO_LOCAL_SEAT) this.jiaoBtnNode.active = false;
        let playerUI = this.players[localSeat];
        playerUI.showJiaoType(true,msg.action)
    }

    onAllJiaoAction(msg:Array<{seat:number,action:BankerAction}>){
        for (let i=0;i<msg.length;i++){
            let item = msg[i];
            let localSeat = PlayerData.serverSeatToLocalSeat(item.seat);
            let playerUI = this.players[localSeat];
            playerUI.showJiaoType(true,item.action)
        }
    }
}